package cn.bonoon.kernel.web.handlers;

import java.lang.reflect.AnnotatedElement;

import cn.bonoon.kernel.events.DialogEvent;
import cn.bonoon.kernel.expression.QueryExpressionParameter;
import cn.bonoon.kernel.support.entities.Persistable;
import cn.bonoon.kernel.support.services.SearchService;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.kernel.web.ButtonRefreshType;
import cn.bonoon.kernel.web.controllers.BaseButtonResolver;
import cn.bonoon.kernel.web.controllers.GridButtonResolver;
import cn.bonoon.kernel.web.controllers.GridToolbarResolver;
import cn.bonoon.kernel.web.html.grid.StandardGridBuilder;
import cn.bonoon.kernel.web.models.DialogModel;
import cn.bonoon.kernel.web.models.IdParameter;
import cn.bonoon.kernel.web.resources.DialogResourceRepository;

/**
 * <pre>
 * 自动生成的弹出对话框，该对话框是一个grid列表
 * 
 * 可以添加查询条件，使用函数{@link #setConditionClass(Class)}
 * 
 * 本对话框默认接受一个来自访问路径的"id"参数，所有在生成该按钮的时候，需要手动设置该id、并且赋值
 * 子类重载该类，也可以重定义需要使用到的参数等
 * </pre>
 * @author jackson
 *
 * @param <E>
 */
public class DialogGridHandler<E extends Persistable> extends AbstractDialogHandler{

	protected final Class<?> itemClass;
	protected final SearchService<E> service;
	protected DialogGridRegister currentRegister;
	
//	/**
//	 * 可以在子类的构造函数中对查询条件进行赋值
//	 */
//	protected Class<?> conditionClass;
	protected DialogResourceRepository resource;
	protected final String relatedId, relatedValue, relatedComponent;
	protected String relatedKey;
	
	public DialogGridHandler(HandlerRegister register, SearchService<E> service, Class<?> itemClass) throws Exception {
		super(itemClass, register);
		this.service = service;
		this.itemClass = itemClass;
		this.currentRegister = new DialogGridRegister(register);
		this.relatedId = "htb_" + key + "_id";
		this.relatedComponent = "<input type='hidden' id='" + relatedId + "' value='$!{form}'/>";
		this.relatedValue = "jQuery('#" + relatedId + "').val()";
	}
	public void setRelatedKey(String relatedKey) {
		this.relatedKey = relatedKey;
	}
	/**
	 * <pre>
	 * 子类型可以重写这个方法，这方法在进行grid列表的初始化({@link #currentRegister}.{@link DialogGridRegister#init() init()})之前被执行
	 * 在此可以向列表添加自定义的查询条件，或其它一些需要在初始化之前进行赋值的操作
	 * </pre>
	 * @param gridRegister
	 * @throws Exception
	 */
	protected void before(DialogGridRegister gridRegister)throws Exception{
		if(StringHelper.isNotEmpty(relatedKey)){
			//TODO 需要修改的地方
//			String ql = "x." + relatedKey + "=?";
			QueryExpressionParameter qp = new QueryExpressionParameter(relatedKey, relatedValue);
			qp.setParameterType("J");
			gridRegister.gridBuilder.addQueryParameter(qp);
		}
	}
	
	
	@Override
	protected void parse(StringBuilder html, StringBuilder block, StringBuilder dlgAttrs) {
		html.append(relatedComponent);
		super.parse(html, block, dlgAttrs);
	}
	
	@Override
	public IdParameter buildParams() {
		return new IdParameter();
	}
	
	protected ButtonRefreshType getButtonRefreshType(){
		return ButtonRefreshType.NONE;
	}
	
	protected void register(BaseButtonResolver resolver, StandardGridBuilder builder) throws Exception{

		this.refreshType = getButtonRefreshType();
		
		//向grid列表传一些参数
		builder.parse();
		resource = new DialogResourceRepository(itemClass.getName(), builder);
		
		StringBuilder html = new StringBuilder();
		StringBuilder dlgAttrs = new StringBuilder();
		parse(html, resource.getBlock(), dlgAttrs);
		html.append("<div id='$!{di.id}' ").append(dlgAttrs).append(" $!{di.dialogAttributes}>");
		html.append(builder.getHtml()).append("</div>");
		
		resource.getBlock().append(block);
		resource.putStringResource(html);
		viewName = resource.getName();
	}
	@Override
	public final BaseButtonResolver register(BaseButtonResolver resolver) throws Exception {
		before(currentRegister);
		register(resolver, currentRegister.init(getClass()));
		return super.register(resolver);
	}

	@Override
	protected void internalExecute(DialogModel model, DialogEvent event) throws Exception {
		model.addBlock(resource.getBlock());
		model.addIncludes(resource.getIncludes());
		model.addScript(resource.getScript());
		model.addLoadEvent(resource.getOnLoadEvent());

		model.addForm(IdParameter.toId(event));
	}
	
//	/**
//	 * <pre>
//	 * 设置查询条件
//	 * 
//	 * 进行赋值应该在注册函数{@link #register(BaseButtonResolver)}被调用之前
//	 * 可以在外部直接赋值；如果是子类，则可以重写{@link #before(DialogGridRegister)}函数进行赋值
//	 * </pre>
//	 * @param conditionClass
//	 */
//	public void setConditionClass(Class<?> conditionClass) {
//		this.conditionClass = conditionClass;
//	}
//	
	/**
	 * <pre>
	 * 向对话框中的grid列表添加toolbar按钮
	 * 
	 * 必须在注册函数{@link #register(BaseButtonResolver)}被调用之前
	 * </pre>
	 * @return
	 */
	public GridToolbarResolver gridToolbar() {
		return currentRegister.toolbar();
	}
	
	/**
	 * <pre>
	 * 向对话框中的grid列表的行添加操作按钮
	 * 
	 * 注册函数{@link #register(BaseButtonResolver)}被调用之前
	 * </pre>
	 * @return
	 */
	public GridButtonResolver gridButton() {
		return currentRegister.button();
	}
	
	protected class DialogGridRegister extends AbstractHandlerRegister{
		
		protected DialogGridRegister(HandlerRegister register) throws Exception {
			super(key, itemClass, register.getManager());
		}

		public StandardGridBuilder init(AnnotatedElement aEle) throws Exception {
//			gridBuilder.addQueryParameters(parameters);
			return gridBuilder.initLoader(service, aEle);
		}
		
//		public void addQueryParams(String name, String value){
//			gridBuilder.addQueryParams(name, value);
//		}

//		public String getId() {
//			return gridBuilder.getId();
//		}

//		public String getGridType() {
//			return gridBuilder.getGridType();
//		}
	}
	
//	public static <P extends Persistable> GridButtonResolver button(
//			HandlerRegister register, 
//			SearchService<P> service, 
//			Class<?> itemClass, 
//			String name, 
//			String title,
//			String relatedKey,
//			int width,
//			int height) throws Exception{
//		return button(register, service, itemClass, null, name, title, relatedKey, width, height);
//	}
	
	public static <P extends Persistable> GridButtonResolver button(
			HandlerRegister register, 
			SearchService<P> service, 
			Class<?> itemClass, 
			String name, 
			String title,
			String relatedKey) throws Exception{
		return button(register, service, itemClass, name, title, relatedKey, 650, 480);
	}
	
	public static <P extends Persistable> GridButtonResolver button(
			HandlerRegister register, 
			SearchService<P> service, 
			Class<?> itemClass, 
//			Class<?> conditionClass, 
			String name, 
			String title,
			String relatedKey,
			int width,
			int height) throws Exception{
		DialogGridHandler<P> cd = new DialogGridHandler<P>(register, service, itemClass);
		cd.set(title, true);
		cd.size(width, height);
		cd.relatedKey = relatedKey;
//		cd.conditionClass = conditionClass;
		GridButtonResolver gbr = register.button();
		gbr.setName(name);
		cd.register(gbr);
		return gbr;
	}
	
//	public static <P extends Persistable> GridButtonResolver button(
//			HandlerRegister register, 
//			SearchService<P> service, 
//			Class<?> itemClass, 
////			Class<?> conditionClass, 
//			String name, 
//			String title,
//			String relatedKey) throws Exception{
//		return button(register, service, itemClass, name, title, relatedKey, 650, 480);
//	}
}
